package algo3.algothief.modelo;

import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class CuartelGeneral {
	
	private String direccionParaCargarAlCuartelGeneral;
	
	private BaseDeDatosDeLadrones ladrones;
	private DescripcionDeLadron descripcionDelSospechosoAlQueSeLeEmitioLaOrden;
	
	private static int horasQueSeTardanEnEmitirUnaOrdenDeArresto = 3;

//-------------------------------------------------------------------------------------
	
	public CuartelGeneral(String direccionDeLasDescripciones) throws ParserConfigurationException, SAXException, IOException {
		this.direccionParaCargarAlCuartelGeneral = direccionDeLasDescripciones;
		
		this.ladrones = new BaseDeDatosDeLadrones(direccionDeLasDescripciones);
		this.descripcionDelSospechosoAlQueSeLeEmitioLaOrden = null;
	}

//-------------------------------------------------------------------------------------

	// La forma de serializar esta escrita lo mas generica posible.
	public Element serializar(Document doc) {
		Element elementoCuartel = doc.createElement("CuartelGeneral");
		
		Element elementoDireccion = doc.createElement("DireccionDeLasDescripciones");
		elementoDireccion.setAttribute("direccion", this.direccionParaCargarAlCuartelGeneral);
		
		Element elementoDescripcion = this.serializarLaDescripcionDelSospechoso(doc);
		
		elementoCuartel.appendChild(elementoDireccion);
		elementoCuartel.appendChild(elementoDescripcion);
			
		return elementoCuartel;
	}

	public static CuartelGeneral hidratar(Document doc) throws ParserConfigurationException, SAXException, IOException {
		Element elementoCuartel = (Element)doc.getElementsByTagName("CuartelGeneral").item(0);
			
		Element elementoDireccion = (Element)elementoCuartel.getElementsByTagName("DireccionDeLasDescripciones").item(0);
		String direccionDeLasDescripciones = elementoDireccion.getAttribute("direccion");
			
		CuartelGeneral cuartelGeneralNuevo = new CuartelGeneral(direccionDeLasDescripciones);
		
		DescripcionDeLadron descripcionDelSospechoso = CuartelGeneral.hidratarLaDescripcionDelSospechoso(doc);
		cuartelGeneralNuevo.modificarDescripcionDelSospechosoAlQueSeLeEmitioLaOrden(descripcionDelSospechoso);	
		
		return cuartelGeneralNuevo;
	}
	
//-------------------------------------------------------------------------------------

	private Element serializarLaDescripcionDelSospechoso(Document doc) {		
		Element elementoDescripcion;
		
		boolean laDescripcionExiste = (this.descripcionDelSospechosoAlQueSeLeEmitioLaOrden != null);
		if (laDescripcionExiste) 
			elementoDescripcion = descripcionDelSospechosoAlQueSeLeEmitioLaOrden.serializar(doc, "AlQueSeLeEmitioLaOrden");
		else
			elementoDescripcion = doc.createElement("DescripcionDeLadron" + "AlQueSeLeEmitioLaOrden");
		
		return elementoDescripcion;
	}
	
	
	
	
	private static DescripcionDeLadron hidratarLaDescripcionDelSospechoso(Document doc) throws ParserConfigurationException, SAXException, IOException {
		DescripcionDeLadron descripcionNueva = DescripcionDeLadron.hidratar(doc, "AlQueSeLeEmitioLaOrden");
		return descripcionNueva;
	}
	
	private void modificarDescripcionDelSospechosoAlQueSeLeEmitioLaOrden(DescripcionDeLadron descripcionDelSospechoso) {
		this.descripcionDelSospechosoAlQueSeLeEmitioLaOrden = descripcionDelSospechoso;
	}
	
//-------------------------------------------------------------------------------------

	public BaseDeDatosDeLadrones verLaBaseDeDatosDeLadrones() {
		return this.ladrones;
	}
	
	public int emitirOrdenDeArresto(DescripcionDeLadron descripcionDelPosibleLadron) {
		ArrayList<DescripcionDeLadron> descripcionesQueConcuerdan = ladrones.verSospechososQueConcuerdanConLaDescripcion(descripcionDelPosibleLadron);
		boolean unSoloLadronConcuerdaConLaDescripcion = (descripcionesQueConcuerdan.size() == 1);
		
		if (unSoloLadronConcuerdaConLaDescripcion) {
			this.descripcionDelSospechosoAlQueSeLeEmitioLaOrden = descripcionesQueConcuerdan.get(0);
			return horasQueSeTardanEnEmitirUnaOrdenDeArresto;
		}
		
		return 0; // No se emitio orden de arresto y por lo tanto no paso tiempo.
	}

	public boolean seEmitioUnaOrdenDeArresto() {
		return (this.descripcionDelSospechosoAlQueSeLeEmitioLaOrden != null);
	}
	
	public boolean verSiConcuerdaConLaDescripcionDelSospechoso(DescripcionDeLadron descripcion) {
		if (descripcionDelSospechosoAlQueSeLeEmitioLaOrden == null) return false;
		return (descripcionDelSospechosoAlQueSeLeEmitioLaOrden.concuerdanLasDescripciones(descripcion));
	}
}
